"""
统一插件管理器
负责MCP插件和自定义插件的加载、注册、管理和生命周期控制
"""

import os
import importlib.util
import json
import asyncio
import logging
import traceback
from typing import Dict, Any, Optional, List, Callable
from .plugin_registry import PluginRegistry
from src.utils.mcp_plugin_loader import MCPPluginLoader
from src.services.plugin_system.plugin_manager import PluginManager as CustomPluginManager

logger = logging.getLogger(__name__)


class UnifiedPluginManager:
    """统一插件管理器"""
    
    # 插件状态常量
    PLUGIN_STATE_LOADED = "loaded"
    PLUGIN_STATE_INITIALIZED = "initialized"
    PLUGIN_STATE_PAUSED = "paused"
    PLUGIN_STATE_RUNNING = "running"
    PLUGIN_STATE_STOPPED = "stopped"
    PLUGIN_STATE_ERROR = "error"
    
    def __init__(self):
        self.registry = PluginRegistry()
        self.mcp_loader = MCPPluginLoader()
        self.custom_plugin_manager = CustomPluginManager()
        self.loaded_plugins: Dict[str, Any] = {}
        self.plugin_states: Dict[str, str] = {}  # 插件状态管理
        self.plugin_dependencies: Dict[str, List[str]] = {}  # 插件依赖关系
        self.plugin_lifecycle_hooks: Dict[str, Dict[str, Callable]] = {}  # 生命周期钩子
        self.plugin_logs: Dict[str, List[str]] = {}  # 插件日志记录
    
    async def initialize(self):
        """初始化插件管理器"""
        logger.info("初始化统一插件管理器")
        # 初始化MCP插件加载器
        # 初始化自定义插件管理器
        logger.info("统一插件管理器初始化完成")
    
    async def load_all_plugins(self):
        """加载所有启用的插件"""
        logger.info("开始加载所有插件")
        
        # 加载MCP插件
        await self._load_mcp_plugins()
        
        # 加载自定义插件
        await self._load_custom_plugins()
        
        logger.info("所有插件加载完成")
    
    async def _load_mcp_plugins(self):
        """加载MCP插件"""
        try:
            mcp_plugins = self.registry.list_plugins("mcp")
            for plugin_name, plugin_info in mcp_plugins.items():
                if plugin_info.get("enabled", True):
                    await self.load_mcp_plugin(plugin_name, plugin_info)
        except Exception as e:
            logger.error(f"加载MCP插件时出错: {e}")
    
    async def _load_custom_plugins(self):
        """加载自定义插件"""
        try:
            custom_plugins = self.registry.list_plugins("custom")
            for plugin_name, plugin_info in custom_plugins.items():
                if plugin_info.get("enabled", True):
                    await self.load_custom_plugin(plugin_name, plugin_info)
        except Exception as e:
            logger.error(f"加载自定义插件时出错: {e}")
    
    async def load_mcp_plugin(self, plugin_name: str, plugin_info: Dict[str, Any]):
        """
        加载MCP插件
        
        Args:
            plugin_name: 插件名称
            plugin_info: 插件信息
        """
        try:
            # 初始化插件日志
            self.plugin_logs[plugin_name] = []
            
            # 检查依赖
            dependencies = plugin_info.get("dependencies", [])
            if not await self._check_dependencies(dependencies):
                logger.warning(f"MCP插件 {plugin_name} 依赖检查失败")
                self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
                self.plugin_logs[plugin_name].append(f"依赖检查失败: {dependencies}")
                return
            
            # 使用现有的MCP插件加载器加载插件
            self.mcp_loader.register_plugin(plugin_name, plugin_info)
            self.loaded_plugins[plugin_name] = {
                "type": "mcp",
                "instance": plugin_info,  # 实际情况下这里应该是插件实例
                "info": plugin_info
            }
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_LOADED
            self.plugin_logs[plugin_name].append("插件加载成功")
            
            # 调用加载后钩子
            await self._call_lifecycle_hook(plugin_name, "on_loaded")
            
            logger.info(f"MCP插件 {plugin_name} 加载成功")
        except Exception as e:
            logger.error(f"加载MCP插件 {plugin_name} 失败: {e}")
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
            if plugin_name in self.plugin_logs:
                self.plugin_logs[plugin_name].append(f"加载失败: {str(e)}")
                self.plugin_logs[plugin_name].append(f"错误详情: {traceback.format_exc()}")
    
    async def load_custom_plugin(self, plugin_name: str, plugin_info: Dict[str, Any]):
        """
        加载自定义插件
        
        Args:
            plugin_name: 插件名称
            plugin_info: 插件信息
        """
        try:
            # 初始化插件日志
            self.plugin_logs[plugin_name] = []
            
            # 检查依赖
            dependencies = plugin_info.get("dependencies", [])
            if not await self._check_dependencies(dependencies):
                logger.warning(f"自定义插件 {plugin_name} 依赖检查失败")
                self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
                self.plugin_logs[plugin_name].append(f"依赖检查失败: {dependencies}")
                return
                
            plugin_path = plugin_info.get("path", "")
            if not plugin_path:
                logger.warning(f"自定义插件 {plugin_name} 路径未指定")
                self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
                self.plugin_logs[plugin_name].append("插件路径未指定")
                return
            
            # 使用自定义插件管理器加载插件
            await self.custom_plugin_manager.load_plugins(plugin_path)
            self.loaded_plugins[plugin_name] = {
                "type": "custom",
                "instance": None,  # 实际情况下这里应该是插件实例
                "info": plugin_info
            }
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_LOADED
            self.plugin_logs[plugin_name].append("插件加载成功")
            
            # 调用加载后钩子
            await self._call_lifecycle_hook(plugin_name, "on_loaded")
            
            logger.info(f"自定义插件 {plugin_name} 加载成功")
        except Exception as e:
            logger.error(f"加载自定义插件 {plugin_name} 失败: {e}")
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
            if plugin_name in self.plugin_logs:
                self.plugin_logs[plugin_name].append(f"加载失败: {str(e)}")
                self.plugin_logs[plugin_name].append(f"错误详情: {traceback.format_exc()}")
    
    def get_plugin(self, plugin_name: str) -> Optional[Any]:
        """
        获取插件实例
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            插件实例或None
        """
        plugin_entry = self.loaded_plugins.get(plugin_name)
        if plugin_entry:
            return plugin_entry.get("instance")
        return None
    
    async def unload_plugin(self, plugin_name: str) -> bool:
        """
        卸载插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            卸载是否成功
        """
        try:
            plugin_entry = self.loaded_plugins.get(plugin_name)
            if not plugin_entry:
                logger.warning(f"插件 {plugin_name} 未加载")
                return False
            
            # 调用卸载前钩子
            await self._call_lifecycle_hook(plugin_name, "on_unloading")
            
            plugin_type = plugin_entry.get("type")
            if plugin_type == "mcp":
                # 卸载MCP插件
                self.mcp_loader.unregister_plugin(plugin_name)
            elif plugin_type == "custom":
                # 卸载自定义插件
                # 这里需要具体实现
                pass
            
            # 从已加载插件中移除
            del self.loaded_plugins[plugin_name]
            if plugin_name in self.plugin_states:
                del self.plugin_states[plugin_name]
            if plugin_name in self.plugin_dependencies:
                del self.plugin_dependencies[plugin_name]
            if plugin_name in self.plugin_lifecycle_hooks:
                del self.plugin_lifecycle_hooks[plugin_name]
                
            logger.info(f"插件 {plugin_name} 卸载成功")
            return True
        except Exception as e:
            logger.error(f"卸载插件 {plugin_name} 失败: {e}")
            return False
    
    async def reload_plugin(self, plugin_name: str) -> bool:
        """
        重新加载插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            重新加载是否成功
        """
        try:
            # 先卸载插件
            await self.unload_plugin(plugin_name)
            
            # 重新加载插件
            plugin_info = self.registry.get_plugin(plugin_name)
            if not plugin_info:
                logger.warning(f"插件 {plugin_name} 未在注册表中找到")
                return False
            
            plugin_type = plugin_info.get("type", "custom")
            if plugin_type == "mcp":
                await self.load_mcp_plugin(plugin_name, plugin_info)
            else:
                await self.load_custom_plugin(plugin_name, plugin_info)
            
            logger.info(f"插件 {plugin_name} 重新加载成功")
            return True
        except Exception as e:
            logger.error(f"重新加载插件 {plugin_name} 失败: {e}")
            return False
    
    def list_loaded_plugins(self) -> Dict[str, Any]:
        """
        列出已加载的插件
        
        Returns:
            已加载的插件列表
        """
        return self.loaded_plugins
    
    async def shutdown(self):
        """关闭插件管理器，卸载所有插件"""
        logger.info("关闭统一插件管理器")
        # 卸载所有插件
        plugin_names = list(self.loaded_plugins.keys())
        for plugin_name in plugin_names:
            await self.unload_plugin(plugin_name)
    
    async def _check_dependencies(self, dependencies: List[str]) -> bool:
        """
        检查插件依赖是否满足
        
        Args:
            dependencies: 依赖列表
            
        Returns:
            依赖是否满足
        """
        for dep in dependencies:
            if dep not in self.loaded_plugins:
                # 尝试加载依赖
                dep_info = self.registry.get_plugin(dep)
                if not dep_info:
                    logger.error(f"依赖 {dep} 不存在")
                    return False
                
                dep_type = dep_info.get("type", "custom")
                if dep_type == "mcp":
                    await self.load_mcp_plugin(dep, dep_info)
                else:
                    await self.load_custom_plugin(dep, dep_info)
                
                # 检查加载是否成功
                if dep not in self.loaded_plugins:
                    logger.error(f"依赖 {dep} 加载失败")
                    return False
        return True
    
    async def _call_lifecycle_hook(self, plugin_name: str, hook_name: str):
        """
        调用插件生命周期钩子
        
        Args:
            plugin_name: 插件名称
            hook_name: 钩子名称
        """
        if plugin_name in self.plugin_lifecycle_hooks:
            hooks = self.plugin_lifecycle_hooks[plugin_name]
            if hook_name in hooks:
                try:
                    await hooks[hook_name]()
                    if plugin_name in self.plugin_logs:
                        self.plugin_logs[plugin_name].append(f"调用生命周期钩子: {hook_name}")
                except Exception as e:
                    logger.error(f"调用插件 {plugin_name} 生命周期钩子 {hook_name} 失败: {e}")
                    if plugin_name in self.plugin_logs:
                        self.plugin_logs[plugin_name].append(f"调用生命周期钩子 {hook_name} 失败: {str(e)}")
    
    def register_lifecycle_hook(self, plugin_name: str, hook_name: str, callback: Callable):
        """
        注册插件生命周期钩子
        
        Args:
            plugin_name: 插件名称
            hook_name: 钩子名称
            callback: 回调函数
        """
        if plugin_name not in self.plugin_lifecycle_hooks:
            self.plugin_lifecycle_hooks[plugin_name] = {}
        self.plugin_lifecycle_hooks[plugin_name][hook_name] = callback
    
    def get_plugin_state(self, plugin_name: str) -> Optional[str]:
        """
        获取插件状态
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            插件状态
        """
        return self.plugin_states.get(plugin_name)
    
    def get_plugin_logs(self, plugin_name: str) -> List[str]:
        """
        获取插件日志
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            插件日志列表
        """
        return self.plugin_logs.get(plugin_name, [])
    
    async def start_plugin(self, plugin_name: str) -> bool:
        """
        启动插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            启动是否成功
        """
        try:
            if plugin_name not in self.loaded_plugins:
                logger.warning(f"插件 {plugin_name} 未加载")
                return False
            
            # 调用启动钩子
            await self._call_lifecycle_hook(plugin_name, "on_start")
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_RUNNING
            if plugin_name in self.plugin_logs:
                self.plugin_logs[plugin_name].append("插件启动成功")
            logger.info(f"插件 {plugin_name} 启动成功")
            return True
        except Exception as e:
            logger.error(f"启动插件 {plugin_name} 失败: {e}")
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
            if plugin_name in self.plugin_logs:
                self.plugin_logs[plugin_name].append(f"插件启动失败: {str(e)}")
            return False
    
    async def stop_plugin(self, plugin_name: str) -> bool:
        """
        停止插件
        
        Args:
            plugin_name: 插件名称
            
        Returns:
            停止是否成功
        """
        try:
            if plugin_name not in self.loaded_plugins:
                logger.warning(f"插件 {plugin_name} 未加载")
                return False
            
            # 调用停止钩子
            await self._call_lifecycle_hook(plugin_name, "on_stop")
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_STOPPED
            if plugin_name in self.plugin_logs:
                self.plugin_logs[plugin_name].append("插件停止成功")
            logger.info(f"插件 {plugin_name} 停止成功")
            return True
        except Exception as e:
            logger.error(f"停止插件 {plugin_name} 失败: {e}")
            self.plugin_states[plugin_name] = self.PLUGIN_STATE_ERROR
            if plugin_name in self.plugin_logs:
                self.plugin_logs[plugin_name].append(f"插件停止失败: {str(e)}")
            return False